#ifndef __COMMON_HPP__
#define __COMMON_HPP__

#include <string>
#include <vector>
#include <stdint.h>
#include <sys/time.h>

#include "uv.h"

#define TCP_RECV_BUFF_SIZE       (200 * 1024 * 1024)
#define TCP_RECV_UVBUFF_SIZE     (65536)

#define TCP_SEND_BUFF_SIZE      (200 * 1024 * 1024)
#define CHUNKS_PER_WRITE        (4096)
#define TCP_SEND_UVBUFF_SIZE    (65536)
/*******************************************************Global*******************************************************************************************/
inline std::string GetUVError(int errcode)
{
    if (0 == errcode) {
        return "";
    }
    std::string err;
    auto tmpChar = uv_err_name(errcode);
    if (tmpChar) {
        err = tmpChar;
        err += ":";
    }else{
		err = "unknown system errcode "+std::to_string((long long)errcode);
		err += ":";
	}
    tmpChar = uv_strerror(errcode);
    if (tmpChar) {
        err += tmpChar;
    }
    return std::move(err);
}

inline void PlayerInfo(std::string funcName, int errcode)
{
    std::string errmsg;
    errmsg = GetUVError(errcode);
    fprintf(stdout, "%s error: %s\n",funcName.c_str(), errmsg.c_str());
}

inline unsigned long long sysGetCurPts(unsigned long long  *std_ticks)
{
    struct timeval tp;
    gettimeofday(&tp, NULL);
    unsigned long long us = tp.tv_sec * 1000000 + tp.tv_usec;
    *std_ticks = us;
    return us;
}

inline int32_t delayMs(uint32_t waitMS)
{
    int maxfd = 0;
    struct timeval TotalWait_tv;
    int rc;

    fd_set readfd;
    TotalWait_tv.tv_sec =  waitMS / 1000; //SECOND
    TotalWait_tv.tv_usec = (waitMS % 1000) * 1000; //USECOND

    // FD_ZERO (&readfd);
    // rc = select (maxfd + 1, &readfd, NULL, NULL, &TotalWait_tv);
    rc = select(0, NULL, NULL, NULL, &TotalWait_tv);

    if (rc < 0){
        return -1;
    }

    return 0;
}

inline int32_t delayUs(uint32_t waitUS)
{
    int maxfd = 0;
    struct timeval TotalWait_tv;
    int rc;

    fd_set readfd;
    TotalWait_tv.tv_sec = 0;
    TotalWait_tv.tv_usec = waitUS;

    // FD_ZERO (&readfd);
    // rc = select (maxfd + 1, &readfd, NULL, NULL, &TotalWait_tv);
    rc = select(0, NULL, NULL, NULL, &TotalWait_tv);

    if (rc < 0){
        return -1;
    }

    return 0;
}

#define FRAME_OFFSET_HEAD       0
#define FRAME_OFFSET_SRC        2
#define FRAME_OFFSET_DEST       3
#define FRAME_OFFSET_RESERVE    4
#define FRAME_OFFSET_CMD        11
#define FRAME_OFFSET_SUBCMD     13
#define FRAME_OFFSET_DATALEN    14
#define FRAME_OFFSET_DATA       16

#endif
